package top.lishuoboy.springmvc.a8;

import cn.hutool.core.util.URLUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.RequestEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import top.lishuoboy.springmvc.a4.bean.User;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 八、HttpMessageConverter
 * HttpMessageConverter，报文信息转换器，将请求报文转换为Java对象，或将Java对象转换为响应报文
 * HttpMessageConverter提供了两个注解和两个类型：@RequestBody，@ResponseBody，RequestEntity，ResponseEntity
 */
@Controller
@RequestMapping("/a8")
@Slf4j
public class HttpMessageConverterController {

    /**
     * 首页
     * http://localhost:8080/lishuoboy_springmvc_war_exploded/a8
     */
    @GetMapping("")
    private String index() {
        return "a8/index";
    }

    /**
     * 1、@RequestBody。【如果是浏览器，必须为post请求,否则没有requestBody，postman、hutool的get请求也可以发请求body】
     *
     * @RequestBody可以获取请求体，需要在控制器方法设置一个形参，使用@RequestBody进行标识，当 前请求的请求体就会为当前注解所标识的形参赋值
     * http://localhost:8080/lishuoboy_springmvc_war_exploded/a8/1
     */
//    @PostMapping("/1")
    @RequestMapping("/1")
    private String requestBody(@RequestBody String requestBody) {
        log.warn("requestBody=={}", URLUtil.decode(requestBody));
        return "public";
    }

    /**
     * 1_2、@RequestBody【补充】，接收json自动转对象
     * 必须设置请求头 Content-Type=application/json
     * 如果是浏览器，必须为post请求,否则没有requestBody，postman、hutool的get请求也可以发请求body
     * 用postman测试
     *
     * @RequestBody可以获取请求体，需要在控制器方法设置一个形参，使用@RequestBody进行标识，当 前请求的请求体就会为当前注解所标识的形参赋值
     * http://localhost:8080/lishuoboy_springmvc_war_exploded/a8/1_2   json为{"id":"111","name":"张三"}
     */
    @RequestMapping("/1_2")
    private String requestBody(@RequestBody Map<String, Object> requestBodyMap) {
        log.warn("requestBodyMap=={}", requestBodyMap);
        log.warn("requestBodyMap=={}", requestBodyMap.getClass());
        log.warn("requestBodyMap.get(\"name\")=={}", requestBodyMap.get("name"));
        return "public";
    }

    /**
     * 2、RequestEntity【get方式没有请求body】
     * RequestEntity封装请求报文的一种类型，需要在控制器方法的形参中设置该类型的形参，当前请求的请求报文就会赋值给该形参，可以通过getHeaders()获取请求头信息，通过getBody()获取请求体信息
     */
    @RequestMapping("/2")
    private String requestEntity(RequestEntity<String> requestEntity, RequestEntity<String> requestEntity2) {
        log.warn("requestEntity=={}", requestEntity);
        log.warn("requestEntity.getMethod()=={}", requestEntity.getMethod());
        log.warn("requestEntity.getUrl()=={}", requestEntity.getUrl());
        log.warn("requestEntity.getHeaders()=={}", requestEntity.getHeaders());
        log.warn("requestEntity.getBody()=={}", requestEntity.getBody());  // 请求方式get时，为null
        log.warn("requestEntity.getType()=={}", requestEntity.getType());  // 请求方式get时，为null

        log.warn("requestEntity2=={}", requestEntity2);

        return "public";
    }

    /**
     * 3、@ResponseBody
     *
     * @ResponseBody用于标识一个控制器方法，可以将该方法的返回值直接作为响应报文的响应体响应到 浏览器，不经过视图解析器解析
     */
    @RequestMapping("/3")
    @ResponseBody
    private String responseBody() {
        log.warn("3、@ResponseBody");
        return "<h1 style='color: red'>public</h1>";
    }

    /**
     * 4、SpringMVC处理json
     * <p>
     * “@ResponseBody”处理json的步骤：
     * a>导入jackson的依赖
     * b>在SpringMVC的核心配置文件中开启mvc的注解驱动，此时在HandlerAdaptor中会自动装配一个消息转换器：MappingJackson2HttpMessageConverter，
     * 可以将响应到浏览器的Java对象转换为Json格式的字符串
     * <mvc:annotation-driven />
     */
    @RequestMapping("/4")
    @ResponseBody
    private Map responseJson() {
        log.warn("4、SpringMVC处理json");
        Map<Object,Object> map = new HashMap();
        map.put(1, 11);
        map.put("string", "张三");
        map.put("date", new Date());
        return map;
    }

    /**
     * 5、SpringMVC处理ajax,接收ajax参数
     */
    @RequestMapping("/5")
    @ResponseBody
//    @ExceptionHandler(Exception.class) // 不加这个异常信息日志都被吞了
    public User testAjax(String name, String hobby, User user) {
        log.warn("name=={}, hobby=={}", name, hobby);
        return user;
    }

    /**
     *  6、@RestController注解
     *  @RestController注解是springMVC提供的一个复合注解，标识在控制器的类上，就相当于为类添加了@Controller注解，并且为其中的每个方法添加了@ResponseBody注解
     */

}
